//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<ImageResource.cpp>
///	@path	~/src/gui/image/
///	@date	2008/06/25
///	@desc	.

#include "config/config.h"

#include "gui/image/ImageResource.h"

namespace xeres {

	// ImageResource
	ImageResource::ImageResource( void )
	{
	}
	// ~ImageResource
	ImageResource::~ImageResource( void )
	{
		for( dict< WString , Image * >::iterator it = m_images.begin() ;
			it != m_images.end() ; ++it )
		{
			delete it->second;
		}
	}

// 	// instance
// 	ImageResource& ImageResource::instance( void )
// 	{
// 		static ImageResource s_ImageResourceInstance;
// 		return s_ImageResourceInstance;
// 	}

	// Some tools for image loading.
	namespace
	{
		inline void __tolower( wchar_t& ch )
		{
			ch = tolower( ch );
		}

		WString format_path( const WString& path )
		{
			WString res( path );
			for_each( res.begin() , res.end() , __tolower );
			normalize_slash( res.begin() , res.end() , '/' );
			return res;
		}
	}
	
	// LoadImage
	RefWeak<IBitmap> ImageResource::LoadImage( const WString& unformatted_path , int frames /*= 0*/ , int starts /*= 0*/ )
	{
		LockGuard<ThreadLock> locker( m_lock );

		WString path = format_path( unformatted_path );

		// Query existing image.
		dict< WString , Image * >::iterator it = m_images.find( path );
		if( it != m_images.end() )
		{
			Image * image = it->second;
			image->m_lastAccess = Time::Now();
			return image->m_bitmap;
		}

		// FIXME: dispatch to different file system by path prefix.

		// Get extension name.
		size_t pos = path.find_last_of( '/' ) + 1;
		WString name = path.substr( pos );
		pos = name.find_last_of( '.' ) + 1;
		WString ext = name.substr( pos );

		dict< WString , Loader >::iterator loader = m_loaders.find( ext );
		if( loader != m_loaders.end() )
		{
			RefPass<IBitmap> bitmap = (loader->second)( path , frames , starts );
			if( bitmap.IsNull() )
			{
				return NULL;
			}

			// Cache it!
			Image * image = new Image;
			image->m_imageSize = bitmap->GetStorageSize();
			image->m_lastAccess = image->m_lastLoad = Time::Now();
			image->m_bitmap = bitmap;
			m_images[ path ] = image;
			return image->m_bitmap;
		}

		// No loader for such type.
		TRACE_ERROR( _S("ImageResource::LoadImage: No registered loader for such type of image '%s'.") , ext.c_str() );

		return NULL;
	}
	// RegisterLoader
	bool ImageResource::RegisterLoader( const WString& ext , Loader loader )
	{
		LockGuard<ThreadLock> locker( m_lock );

		if( m_loaders.has_key( ext ) )
		{
			TRACE_ERROR( _S("ImageResource::RegisterLoader: Loader for '%s' has been registered.") , ext.c_str() );
			return false;
		}
		m_loaders[ ext ] = loader;
		return true;
	}
	
} // namespace xeres
